{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "toc_visible": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# Set up Knowledge Graph\n",
        "- LLM creates a KG\n",
        "- Retrive info from a KG by using LLM"
      ],
      "metadata": {
        "id": "lcegckVQU9ZU"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "2m_YDg2FNMXF",
        "outputId": "1d7102ba-7f22-41f7-8a38-61f18cec7438"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.4/50.4 kB\u001b[0m \u001b[31m337.1 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m1.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.3/2.3 MB\u001b[0m \u001b[31m1.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m207.2/207.2 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m52.0/52.0 kB\u001b[0m \u001b[31m1.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m91.1/91.1 kB\u001b[0m \u001b[31m1.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m294.6/294.6 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m365.7/365.7 kB\u001b[0m \u001b[31m2.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.1/1.1 MB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m40.4/40.4 kB\u001b[0m \u001b[31m1.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m76.4/76.4 kB\u001b[0m \u001b[31m1.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m1.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m318.9/318.9 kB\u001b[0m \u001b[31m1.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m396.4/396.4 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m290.0/290.0 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.5/4.5 MB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.3/49.3 kB\u001b[0m \u001b[31m1.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m141.9/141.9 kB\u001b[0m \u001b[31m1.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m1.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ],
      "source": [
        "!pip install --upgrade --quiet langchain langchain_community langchain_experimental langchain_openai langgraph neo4j openai tiktoken langchain-nvidia-ai-endpoints"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### **Set up Project Variables and Import Database**"
      ],
      "metadata": {
        "id": "CPb9lS0qSZMF"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain.graphs import Neo4jGraph\n",
        "from langchain_openai import ChatOpenAI\n",
        "from google.colab import userdata\n",
        "from langchain_nvidia_ai_endpoints import ChatNVIDIA\n",
        "import os\n",
        "\n",
        "os.environ[\"OPENAI_API_KEY\"] = userdata.get('OPENAI_API_KEY')\n",
        "os.environ[\"NEO4J_URI\"] = \"bolt://52.3.231.218:7687\"\n",
        "os.environ[\"NEO4J_USERNAME\"] = \"neo4j\"\n",
        "os.environ[\"NEO4J_PASSWORD\"] = \"towel-chamber-beacon\"\n",
        "\n",
        "\n",
        "graph = Neo4jGraph()\n",
        "llm = ChatOpenAI(temperature=0 ,model=\"gpt-3.5-turbo\")"
      ],
      "metadata": {
        "id": "G9TvGy3UPdd-"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "llmOllama.invoke(\"What is Neo4j?\").content"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 296
        },
        "id": "lnfyf9IKe6SX",
        "outputId": "ffcd29dd-8d1f-45ef-ecf9-7ecca77f2404"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'Neo4j is a graph database management system that stores data in the form of nodes and relationships rather than tables and columns like traditional relational databases. This allows for efficient querying and manipulation of complex, interconnected data.\\n\\nHere are some key features and concepts of Neo4j:\\n\\n**Key Features:**\\n\\n1. **Graph data model**: Neo4j stores data as a graph, consisting of nodes (entities) and relationships (edges) between them.\\n2. **NoSQL**: Neo4j is a NoSQL database, which means it does not use a fixed schema or rigid data structure like relational databases.\\n3. **Scalability**: Neo4j is designed to handle large amounts of data and scale horizontally to support growing datasets.\\n4. **ACID compliance**: Neo4j ensures atomicity, consistency, isolation, and durability (ACID) for transactions, ensuring data integrity.\\n\\n**Use cases:**\\n\\n1. **Social networks**: Analyzing relationships between users, like friendships or followers.\\n2. **Recommendation engines**: Building personalized recommendations based on user behavior and item relationships.\\n3. **Data integration**: Connecting disparate data sources and querying the integrated data.\\n4. **Network analytics**: Modeling and analyzing complex networks, like transportation or communication networks.\\n5. **Knowledge graphs**: Constructing graphs to represent knowledge and relationships in domains like medicine, law, or finance.\\n\\n**Data Modeling:**\\n\\nIn Neo4j, data is represented as nodes and relationships:\\n\\n* **Nodes**: Represent entities with properties (key-value pairs).\\n* **Relationships**: Connect nodes and have their own properties, like weights or labels.\\n* **Labels**: Assign categories or types to nodes and relationships.\\n* **Properties**: Additional metadata about nodes and relationships.\\n\\n**Querying:**\\n\\nNeo4j provides a powerful query language called Cypher, which allows users to query the graph using patterns and relationships.\\n\\n**Cypher Example:**\\n```\\nMATCH (u: User {name: \"Alice\"})-[:FOLLOWED_BY]->(friend)\\nRETURN friend.name AS FriendName\\n```\\nThis query finds users who follow Alice and returns their names.\\n\\nOverall, Neo4j is a powerful tool for modeling, storing, and querying complex, interconnected data, making it a popular choice in various industries and applications.'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 54
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Test LLM\n",
        "\n",
        "reponse = llm.invoke(\"What is Neo4j?\")\n",
        "print(reponse.content)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "e8qosRckTsXo",
        "outputId": "b65c2dcb-a844-4bdd-caa8-2122a166d514"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Neo4j is a graph database management system that is designed to store, retrieve, and manage data in the form of nodes, relationships, and properties. It is a highly scalable and flexible database that is optimized for handling complex and interconnected data. Neo4j uses a graph-based data model, which allows for efficient querying and analysis of relationships between data points. It is commonly used in applications that require complex data modeling, such as social networks, recommendation engines, and fraud detection systems.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Test Graph\n",
        "\n",
        "graph.get_schema"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 69
        },
        "id": "vf-HFC_-UJBW",
        "outputId": "a8972a2a-2cbb-41eb-f382-886030a90672"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'Node properties:\\nPerson {name: STRING, profession: STRING, age: INTEGER}\\nCity {name: STRING}\\nRelationship properties:\\n\\nThe relationships:\\n(:Person)-[:FRIENDS_WITH]->(:Person)\\n(:Person)-[:VISITED]->(:Person)\\n(:Person)-[:WORKED_WITH]->(:Person)\\n(:Person)-[:NEIGHBOR_OF]->(:Person)\\n(:Person)-[:PARTNER_WITH]->(:Person)\\n(:Person)-[:HAS_CHILD]->(:Person)\\n(:Person)-[:CHILD_OF]->(:Person)\\n(:Person)-[:MARRIED_TO]->(:Person)\\n(:City)-[:CONTAINS]->(:Person)'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 27
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## **Create Knowledge Graphs**\n",
        "\n",
        "### **Two methods:**\n",
        "\n",
        "\n",
        "1. Custom Method\n",
        "\n",
        "2. Langchain Graph Transformers"
      ],
      "metadata": {
        "id": "oRlqrREiU9BB"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "#Custom method\n",
        "\n",
        "from langchain_core.prompts import ChatPromptTemplate\n",
        "from langchain_core.messages import SystemMessage\n",
        "from langchain_core.output_parsers import StrOutputParser\n",
        "\n",
        "\n",
        "prompt = ChatPromptTemplate.from_messages([\n",
        "    SystemMessage(content=\"\"\"\n",
        "    You are a helpful assistant in creates knowledge graphs by Generating Cypher Queries.\\n\n",
        "\n",
        "    Task:\n",
        "     *  Identify Entities, Relationships and Property Keys from Context.\\n\n",
        "     *  Generate Cypher Query to Create Knowledge Graph from the Entities Relationships and Property Keys discovered.\\n\n",
        "     *  Extract ALL Entities and RelationShips as Possible.\\n\n",
        "     *  Always extract a person Profession as an Entity.\\n\n",
        "     *  Be creative.\n",
        "     *  Understand hidden relationships from the network.\n",
        "     Note: Read the Context twice and carefully before generating Cypher Query.\\n\n",
        "     Note: Do not return anything other than the Cypher Query.\\n\n",
        "     Note: Do not include any explanations or apologies in your responses.\\n\n",
        "\n",
        "\n",
        "     Note: Do not hallucinate.\\n\n",
        "\n",
        "     Entities include Person, Place, Product, WorkPlaces, Companies , City, Country, Animals, Tags like peoples Profession and more \\n\n",
        "\n",
        "     Few Shot Prompts:\n",
        "      Example Context:\n",
        "\n",
        "       Mary was born in 1995. She is Friends with Jane and John. Jane is 2 years older than Mary.\n",
        "       Mary has a dog named Max,and is 3 years old. She is also married to John.Mary is from USA and a Software Engineer.\n",
        "\n",
        "      Answer:\n",
        "        MERGE (Mary:Person {name: \"Mary\", birth_year: 1995})\n",
        "        MERGE (Jane:Person {name: \"Jane\", age:1993})\n",
        "        MERGE (John:Person {name: \"John\"})\n",
        "        MERGE (Mary)-[:FRIENDS_WITH]->(Jane)\n",
        "        MERGE (Mary)-[:FRIENDS_WITH]->(John)\n",
        "        MERGE (Jane)-[:FRIENDS_WITH]->(Mary)\n",
        "        MERGE (John)-[:FRIENDS_WITH]->(Mary)\n",
        "        MERGE (Mary)-[:HAS_DOG]->(Max:Dog {name: \"Max\", age: 3})\n",
        "        MERGE (Mary)-[:MARRIED_TO]->(John)\n",
        "        MERGE (Mary)-[:HAS_PROFESSION]->(SoftwareEngineer:Profession {name: \"Software Engineer\"})\n",
        "        MERGE (Mary)-[:FROM]->(USA:Country {name: \"USA\"})\n",
        "\n",
        "\n",
        "    \"\"\"),\n",
        "    (\"human\", \"Context:{text}\"),\n",
        "])\n",
        "\n",
        "chain  = prompt | llm | StrOutputParser()"
      ],
      "metadata": {
        "id": "BlMEwnzEU3bF"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "content = \"\"\n",
        "# Open the file in read mode\n",
        "with open('FictionalStory.txt', 'r') as file:\n",
        "    # Read the contents of the file\n",
        "    content = file.read()\n",
        "\n",
        "# Print the content\n",
        "print(content)\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "D8ClBxdTZHTp",
        "outputId": "81fe3e2c-9775-4626-b083-f4888aec8883"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "### The Enchanted Network of NexCity\n",
            "\n",
            "---\n",
            "\n",
            "In the heart of the bustling metropolis of **NexCity**, where skyscrapers kissed the clouds and neon lights painted the night, lived Emma Thompson. Her apartment was a marvel of modern design, perched high above the city streets, a shimmering beacon of her success as a software developer. Little did she know, her life was about to become a thrilling tapestry of connections, adventures, and surprises.\n",
            "\n",
            "#### **Chapter 1: The Birthday Bash**\n",
            "\n",
            "One sunny Saturday, Emma received an invitation from her childhood friend, Alex Martin. Alex, now a thriving entrepreneur, lived in a charming suburban house with his partner, Jessica, and their two playful children, Lily and Max. The occasion? Max’s fifth birthday party, and it promised to be a grand affair.\n",
            "\n",
            "Emma arrived at Alex's home to find the backyard transformed into a carnival. Colorful balloons floated in the breeze, and laughter echoed as children darted around a bouncy castle. Emma marveled at the festive atmosphere and caught up with old friends, including Tom Wilson and his wife Sarah. Tom was a senior developer at Emma’s tech startup, Innovatech, and Sarah was an acclaimed artist. Their loft, just a short drive away, was known for its stunning murals and eclectic style.\n",
            "\n",
            "As Emma mingled, she spotted Maria Lopez, her old university friend who now led an environmental research institute. Maria’s presence was a reminder of their shared past, and they quickly fell into a conversation about their latest projects. Emma was excited to hear about Maria’s groundbreaking work in sustainable technologies.\n",
            "\n",
            "#### **Chapter 2: The Culinary Delight**\n",
            "\n",
            "As the party wound down, Emma made her way to Jake Anderson’s popular restaurant in the Cultural District. Jake’s eatery was renowned for its inventive fusion dishes, blending traditional recipes with a modern twist. Emma, Alex, and Jessica were regulars here, and tonight was no exception.\n",
            "\n",
            "Jake greeted Emma with a warm smile as he presented his latest culinary creations. The evening was filled with delectable flavors and lively conversations, including a fascinating discussion with Raj Patel, a rising star in data science at Innovatech. Raj’s partner, Nina, had organized a community garden project that Emma was eager to hear about.\n",
            "\n",
            "#### **Chapter 3: The Seminar and the Community**\n",
            "\n",
            "The next day, Emma attended a seminar at the NexCity Business Hub, where professionals from various fields gathered. Raj was presenting a new tech solution for Nina’s urban garden, a project Emma had previously collaborated on. The seminar was a whirlwind of ideas, and Emma’s discussions with Leo Martinez, a savvy financial analyst, and Maya Chen, an innovative startup founder, left her buzzing with inspiration.\n",
            "\n",
            "Later that week, Emma received a text from Helen Carter, her retired teacher neighbor. Helen was hosting a book club meeting, and Emma eagerly accepted the invitation. Helen’s home was a cozy haven, filled with the aroma of freshly brewed coffee and the lively chatter of book lovers.\n",
            "\n",
            "#### **Chapter 4: A Wedding to Remember**\n",
            "\n",
            "The following weekend brought a special event—Chloe Edwards and Liam’s wedding. Chloe was Helen’s daughter, and her marriage to Liam, a local journalist, was celebrated with a vibrant street party. The festivities were a joyful reunion of Emma’s friends and acquaintances, each adding their unique touch to the celebration.\n",
            "\n",
            "The wedding was a grand affair, and Emma found herself enjoying the lively music and heartfelt speeches. The event underscored the deep connections that bound NexCity’s residents together, from the childhood friendships of Alex and Emma to the professional ties with Raj and Maya.\n",
            "\n",
            "#### **Chapter 5: The Ongoing Tapestry**\n",
            "\n",
            "As the seasons changed, so did the dynamic fabric of NexCity. Emma continued to weave her way through a rich tapestry of interactions. She explored new culinary delights at Jake’s restaurant, collaborated on tech projects with Maya, and engaged in community initiatives with Raj and Nina. Each day brought new adventures and deeper connections.\n",
            "\n",
            "NexCity was more than just a place; it was a living, breathing network of relationships, milestones, and shared experiences. Emma’s life was a testament to the vibrant interplay of personal and professional connections that defined this extraordinary city.\n",
            "\n",
            "In NexCity, every person’s story added a new thread to the grand tapestry of life. Emma’s journey through this enchanted metropolis was a reminder that the magic of human connection was the true essence of the city. And so, in the heart of NexCity, the story of Emma and her friends continued, weaving a never-ending tale of friendship, love, and adventure.\n",
            "\n",
            "---\n",
            "\n",
            "And as the city lights flickered into the night, the enchanting network of NexCity shimmered with the promise of new stories and connections yet to be discovered.\n",
            "\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "result = chain.invoke({\"text\": content})\n",
        "print(result)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "RcIj-LlgZn4o",
        "outputId": "20c853a4-32b6-47c5-fbfe-3ea035bc5790"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "MERGE (Emma:Person {name: \"Emma Thompson\"})\n",
            "MERGE (NexCity:City {name: \"NexCity\"})\n",
            "MERGE (Alex:Person {name: \"Alex Martin\", profession: \"Entrepreneur\"})\n",
            "MERGE (Jessica:Person {name: \"Jessica\", profession: \"Unknown\"})\n",
            "MERGE (Lily:Person {name: \"Lily\", profession: \"Unknown\"})\n",
            "MERGE (Max:Person {name: \"Max\", profession: \"Unknown\", age: 5})\n",
            "MERGE (Tom:Person {name: \"Tom Wilson\", profession: \"Senior Developer\"})\n",
            "MERGE (Sarah:Person {name: \"Sarah\", profession: \"Artist\"})\n",
            "MERGE (Maria:Person {name: \"Maria Lopez\", profession: \"Research Institute Leader\"})\n",
            "MERGE (Jake:Person {name: \"Jake Anderson\", profession: \"Chef\"})\n",
            "MERGE (Raj:Person {name: \"Raj Patel\", profession: \"Data Scientist\"})\n",
            "MERGE (Nina:Person {name: \"Nina\", profession: \"Unknown\"})\n",
            "MERGE (Leo:Person {name: \"Leo Martinez\", profession: \"Financial Analyst\"})\n",
            "MERGE (Maya:Person {name: \"Maya Chen\", profession: \"Startup Founder\"})\n",
            "MERGE (Helen:Person {name: \"Helen Carter\", profession: \"Retired Teacher\"})\n",
            "MERGE (Chloe:Person {name: \"Chloe Edwards\", profession: \"Unknown\"})\n",
            "MERGE (Liam:Person {name: \"Liam\", profession: \"Journalist\"})\n",
            "\n",
            "MERGE (Alex)-[:FRIENDS_WITH]->(Emma)\n",
            "MERGE (Alex)-[:PARTNER]->(Jessica)\n",
            "MERGE (Alex)-[:CHILD]->(Lily)\n",
            "MERGE (Alex)-[:CHILD]->(Max)\n",
            "MERGE (Emma)-[:FRIENDS_WITH]->(Tom)\n",
            "MERGE (Tom)-[:WORKS_AT]->(Innovatech)\n",
            "MERGE (Tom)-[:PARTNER]->(Sarah)\n",
            "MERGE (Maria)-[:FRIENDS_WITH]->(Emma)\n",
            "MERGE (Maria)-[:LEADS]->(ResearchInstitute)\n",
            "MERGE (Emma)-[:VISITED]->(Alex)\n",
            "MERGE (Emma)-[:VISITED]->(Jake)\n",
            "MERGE (Emma)-[:VISITED]->(Helen)\n",
            "MERGE (Raj)-[:PARTNER]->(Nina)\n",
            "MERGE (Raj)-[:WORKS_AT]->(Innovatech)\n",
            "MERGE (Emma)-[:COLLABORATED_WITH]->(Raj)\n",
            "MERGE (Emma)-[:COLLABORATED_WITH]->(Maya)\n",
            "MERGE (Emma)-[:ATTENDED]->(NexCityBusinessHub)\n",
            "MERGE (Leo)-[:WORKS_AT]->(NexCityBusinessHub)\n",
            "MERGE (Maya)-[:FOUNDER_OF]->(Startup)\n",
            "MERGE (Helen)-[:NEIGHBOR]->(Emma)\n",
            "MERGE (Helen)-[:HOSTS]->(BookClub)\n",
            "MERGE (Chloe)-[:CHILD_OF]->(Helen)\n",
            "MERGE (Chloe)-[:MARRIED_TO]->(Liam)\n",
            "MERGE (Liam)-[:WORKS_AS]->(Journalist)\n",
            "MERGE (Chloe)-[:FRIENDS_WITH]->(Emma)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "def create_knowledge_graph(cypher:str):\n",
        "    graph.query(cypher)"
      ],
      "metadata": {
        "id": "vIUeP76ddL-J"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "create_knowledge_graph(f\"\"\"{result}\"\"\")"
      ],
      "metadata": {
        "id": "vN9voVK1ePdV"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "#Method 2\n",
        "\n",
        "from langchain_core.documents import Document\n",
        "from langchain_experimental.graph_transformers import LLMGraphTransformer\n",
        "\n",
        "llm_transformer = LLMGraphTransformer(llm=llm)\n",
        "documents = [Document(page_content=content)]\n",
        "graph_documents = llm_transformer.convert_to_graph_documents(documents)\n",
        "print(f\"Nodes:{graph_documents[0].nodes}\")\n",
        "print(f\"Relationships:{graph_documents[0].relationships}\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "vdggQKXdo_1P",
        "outputId": "b3e1ac17-e4f3-41c0-f306-87ac7836cea7"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Nodes:[Node(id='Emma Thompson', type='Person'), Node(id='Nexcity', type='City'), Node(id='Alex Martin', type='Person'), Node(id='Jessica', type='Person'), Node(id='Lily', type='Person'), Node(id='Max', type='Person'), Node(id='Tom Wilson', type='Person'), Node(id='Sarah', type='Person'), Node(id='Maria Lopez', type='Person'), Node(id='Jake Anderson', type='Person'), Node(id='Raj Patel', type='Person'), Node(id='Nina', type='Person'), Node(id='Leo Martinez', type='Person'), Node(id='Maya Chen', type='Person'), Node(id='Helen Carter', type='Person'), Node(id='Chloe Edwards', type='Person'), Node(id='Liam', type='Person')]\n",
            "Relationships:[Relationship(source=Node(id='Emma Thompson', type='Person'), target=Node(id='Nexcity', type='City'), type='RESIDENT'), Relationship(source=Node(id='Alex Martin', type='Person'), target=Node(id='Nexcity', type='City'), type='RESIDENT'), Relationship(source=Node(id='Jessica', type='Person'), target=Node(id='Nexcity', type='City'), type='RESIDENT'), Relationship(source=Node(id='Lily', type='Person'), target=Node(id='Nexcity', type='City'), type='RESIDENT'), Relationship(source=Node(id='Max', type='Person'), target=Node(id='Nexcity', type='City'), type='RESIDENT'), Relationship(source=Node(id='Tom Wilson', type='Person'), target=Node(id='Emma Thompson', type='Person'), type='COLLEAGUE'), Relationship(source=Node(id='Sarah', type='Person'), target=Node(id='Tom Wilson', type='Person'), type='SPOUSE'), Relationship(source=Node(id='Maria Lopez', type='Person'), target=Node(id='Emma Thompson', type='Person'), type='FRIEND'), Relationship(source=Node(id='Jake Anderson', type='Person'), target=Node(id='Nexcity', type='City'), type='BUSINESS_OWNER'), Relationship(source=Node(id='Raj Patel', type='Person'), target=Node(id='Jake Anderson', type='Person'), type='ACQUAINTANCE'), Relationship(source=Node(id='Nina', type='Person'), target=Node(id='Raj Patel', type='Person'), type='PARTNER'), Relationship(source=Node(id='Emma Thompson', type='Person'), target=Node(id='Raj Patel', type='Person'), type='COLLEAGUE'), Relationship(source=Node(id='Leo Martinez', type='Person'), target=Node(id='Emma Thompson', type='Person'), type='ACQUAINTANCE'), Relationship(source=Node(id='Maya Chen', type='Person'), target=Node(id='Emma Thompson', type='Person'), type='COLLABORATOR'), Relationship(source=Node(id='Helen Carter', type='Person'), target=Node(id='Emma Thompson', type='Person'), type='NEIGHBOR'), Relationship(source=Node(id='Chloe Edwards', type='Person'), target=Node(id='Helen Carter', type='Person'), type='DAUGHTER'), Relationship(source=Node(id='Liam', type='Person'), target=Node(id='Chloe Edwards', type='Person'), type='SPOUSE')]\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "graph.add_graph_documents(graph_documents)"
      ],
      "metadata": {
        "id": "72Wxh7fLp85v"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### **Querying the Graph**"
      ],
      "metadata": {
        "id": "1oADVlPFr290"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain.chains import GraphCypherQAChain\n",
        "\n",
        "graphchain = GraphCypherQAChain.from_llm(\n",
        "    llm, graph=graph, verbose=True, return_intermediate_steps=True\n",
        ")"
      ],
      "metadata": {
        "id": "L0JTTNPBr1eX"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "results = graphchain.invoke({\"query\":\"People who have kids\"})\n",
        "print(results[\"result\"])"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "t3zzxWPFsMR_",
        "outputId": "0afc934e-2ce6-4645-803b-385306b88c4c"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\n",
            "\u001b[1m> Entering new GraphCypherQAChain chain...\u001b[0m\n",
            "Generated Cypher:\n",
            "\u001b[32;1m\u001b[1;3mMATCH (p1:Person)-[:HAS_CHILD]->(p2:Person)\n",
            "RETURN p1, p2\u001b[0m\n",
            "Full Context:\n",
            "\u001b[32;1m\u001b[1;3m[{'p1': {'profession': 'Entrepreneur', 'name': 'Alex Martin'}, 'p2': {'profession': 'Unknown', 'name': 'Lily'}}, {'p1': {'profession': 'Entrepreneur', 'name': 'Alex Martin'}, 'p2': {'profession': 'Unknown', 'name': 'Max', 'age': 5}}]\u001b[0m\n",
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "Alex Martin, Max have kids.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "os.environ[\"LANGCHAIN_TRACING_V2\"]=\"true\"\n",
        "os.environ[\"LANGCHAIN_ENDPOINT\"]=\"https://api.smith.langchain.com\"\n",
        "os.environ[\"LANGCHAIN_API_KEY\"]=userdata.get('LANGCHAIN_API_KEY')\n",
        "os.environ[\"LANGCHAIN_PROJECT\"]=\"pr-shadowy-latex-56\""
      ],
      "metadata": {
        "id": "zqlLxxrmv-hK"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### **Prompting**"
      ],
      "metadata": {
        "id": "ZlEt5lfDuDHB"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "graph_prompt = ChatPromptTemplate.from_messages([\n",
        "  (\"system\",\n",
        "   f\"\"\"\n",
        "    You are a Cypher Expert Generating Cypher Queries to query a Neo4j Database from User Questions.\\n\n",
        "\n",
        "    Task:\n",
        "      *  Use the schema provided to generate Cypher Queries.\\n\n",
        "      *  Strictly follow the schema while generating Cypher Queries.\\n\n",
        "      *  Do not return any explanations or apologies in your responses.\\n\n",
        "      *  Do not return anything other than cypher queries.\n",
        "      * use fullnames for cypher variables\n",
        "\n",
        "    \"\"\"),\n",
        "    (\"human\",\"Schema: {schema}\"),\n",
        "    (\"human\",\"The question is: {query}\") ,\n",
        "\n",
        "  ]\n",
        ")\n",
        "\n",
        "qa_prompt = ChatPromptTemplate.from_messages([\n",
        "    (\"system\",\"\"\"\n",
        "    You are a Chat Assistant helping users with their queries.\n",
        "    Task: You are to generate answers to the Question asked using the result from context provided. Be concise and provide all relevant information from context.\n",
        "\n",
        "    Instructions:\n",
        "    - Read the question and the context again before answering.\n",
        "    - Use only the provided context to answer the question.\n",
        "    - If no context is provided, explain to the user you could not find that information.\n",
        "    - Do not fall back to your pre-trained knowledge.\n",
        "    - Do not mention context in your answer.\n",
        "    - Be as helpful as you can.\n",
        "    - Do not hallucinate.\n",
        "    - Make sure to provide answer from context before saying you don't know.\n",
        "\n",
        "\n",
        "\n",
        "    Note: The context provided comes from an Authoritative and is a fact source do not doubt it .\n",
        "    Note: Do not fallback to your pre-trained knowledge.\n",
        "    Note: Provide the answer an do not mention you are providing the answer from the context.\n",
        "\n",
        "    *Be friendly with your with your tone.\n",
        "    \"\"\"),\n",
        "\n",
        "    (\"human\",\"Question:{question}\"),\n",
        "    (\"human\",\"Context:{context}\"),\n",
        "])\n",
        "\n",
        "second_graphQa = GraphCypherQAChain.from_llm(\n",
        "    llm=llm, qa_llm=llm,  graph=graph, verbose=True, cypher_prompt=graph_prompt, return_intermediate_steps=True, qa_prompt=qa_prompt\n",
        ")"
      ],
      "metadata": {
        "id": "JqH0evobt9a9"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "result = second_graphQa.invoke({\"query\":\"People who have kids?\"})\n",
        "print(result[\"result\"])"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "VmmmZ38vvokp",
        "outputId": "08ef5c7b-7473-41ca-c3bd-b52c3f1081cb"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\n",
            "\u001b[1m> Entering new GraphCypherQAChain chain...\u001b[0m\n",
            "Generated Cypher:\n",
            "\u001b[32;1m\u001b[1;3mMATCH (p:Person)-[:HAS_CHILD]->(c:Person)\n",
            "RETURN p, c;\u001b[0m\n",
            "Full Context:\n",
            "\u001b[32;1m\u001b[1;3m[{'p': {'profession': 'Entrepreneur', 'name': 'Alex Martin'}, 'c': {'profession': 'Unknown', 'name': 'Lily'}}, {'p': {'profession': 'Entrepreneur', 'name': 'Alex Martin'}, 'c': {'profession': 'Unknown', 'name': 'Max', 'age': 5}}]\u001b[0m\n",
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "Alex Martin has a child named Max who is 5 years old. Lily's profession is unknown.\n"
          ]
        }
      ]
    }
  ]
}